package com.example.aicloud.controller;

import com.alibaba.cloud.ai.tongyi.chat.TongYiChatClient;
import com.alibaba.cloud.ai.tongyi.chat.TongYiChatOptions;
import com.alibaba.cloud.ai.tongyi.image.TongYiImagesClient;
import com.alibaba.cloud.ai.tongyi.image.TongYiImagesOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.aicloud.entity.Answer;
import com.example.aicloud.entity.enums.AiModelEnum;
import com.example.aicloud.entity.enums.AiTypeEnum;
import com.example.aicloud.service.IAnswerService;
import com.example.aicloud.util.AppVariable;
import com.example.aicloud.util.MinioUtil;
import com.example.aicloud.util.ResponseEntity;
import com.example.aicloud.util.SecurityUtil;
import jakarta.annotation.Resource;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.image.Image;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/tongyi")
public class TongYiController {
    @Resource
    private TongYiChatClient chatClient;
    @Resource
    private TongYiImagesClient imageClient;
    @Resource
    private IAnswerService answerService;
    @Resource
    private MinioUtil minioUtil;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @PostMapping("/chat")
    public ResponseEntity chat(String question) {
        if (!StringUtils.hasLength(question)){
            // 输入为空
            return ResponseEntity.fail("输入内容不能为空!");
        }
        String result= "";  // 大模型返回结果
        boolean addResult = false; // 数据添加状态
        // 执行分布式锁
        // key
        String lockKey = AppVariable.getModelLockKey(SecurityUtil.getCurrentUser().getUid(), AiModelEnum.TONGYI.getValue(), AiTypeEnum.CHAT.getValue());
        // 1. 获取分布式锁实例
        RLock rLock = redissonClient.getLock(lockKey);
        try {
            // 2. 获取分布式锁
            boolean isLock = rLock.tryLock(30, TimeUnit.SECONDS); //设置最长等待时间30秒
            if (!isLock){
                return ResponseEntity.fail("请勿频繁调用接口！");
            }
            result=chatClient.call(new Prompt(question, TongYiChatOptions.builder()
                    .withModel("qwen-plus")
                    .build())).getResult().getOutput().getContent();
            // 将结果保存到数据库
            Answer answer=Answer.builder()
                    .title(question)
                    .model(AiModelEnum.TONGYI.getValue())
                    .type(AiTypeEnum.CHAT.getValue())
                    .uid(SecurityUtil.getCurrentUser().getUid())
                    .content(result)
                    .build();
            addResult = answerService.save(answer);
        }catch (Exception e){

        }finally {
            // 3. 释放分布式锁
            rLock.unlock();
        }
        if (addResult){
            return ResponseEntity.success(result);
        }else {
            return ResponseEntity.fail("数据保存失败，请重试！");
        }
    }

    @PostMapping("/draw")
    public ResponseEntity draw(String question) {
        if (!StringUtils.hasLength(question)){
            // 输入为空
            return ResponseEntity.fail("输入内容不能为空!");
        }
        String imgUrl= "";  // 大模型返回结果
        boolean addResult = false; // 数据添加状态
        // 执行分布式锁
        // key
        String lockKey = AppVariable.getModelLockKey(SecurityUtil.getCurrentUser().getUid(), AiModelEnum.TONGYI.getValue(), AiTypeEnum.DRAW.getValue());
        // 1. 获取分布式锁实例
        RLock rLock = redissonClient.getLock(lockKey);
        try {
            // 2. 获取分布式锁
            boolean isLock = rLock.tryLock(30, TimeUnit.SECONDS); //设置最长等待时间30秒
            if (!isLock){
                return ResponseEntity.fail("请勿频繁调用接口！");
            }
            Image image = imageClient.call(new ImagePrompt(question, TongYiImagesOptions.builder()
                    .withHeight(256)
                    .withWidth(256)
                    .build())).getResult().getOutput();
            String base64 =  image.getB64Json();
            // 图片存储在 Minio里
            String imageName = "ty-draw-"+ UUID.randomUUID().toString().replace("-","");
            try (ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(base64))){
                imgUrl = minioUtil.upload(imageName, inputStream, "image/png");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            // 将结果保存到数据库
            Answer answer=Answer.builder()
                    .title(question)
                    .model(AiModelEnum.TONGYI.getValue())
                    .type(AiTypeEnum.DRAW.getValue())
                    .uid(SecurityUtil.getCurrentUser().getUid())
                    .content(imgUrl)
                    .build();
            addResult = answerService.save(answer);
        }catch (Exception e){

        }finally {
            rLock.unlock();
        }
        if (addResult){
            return ResponseEntity.success(imgUrl);
        }else {
            return ResponseEntity.fail("数据保存失败，请重试！");
        }
    }

    /**
     * 获取 TongYi 聊天历史信息
     */
    @PostMapping("/getchatlist")
    private ResponseEntity getChatList(){
        Long uid = SecurityUtil.getCurrentUser().getUid();
        int type= AiTypeEnum.CHAT.getValue();
        int model = AiModelEnum.TONGYI.getValue();
        String cacheKey = AppVariable.getListCacheKey(uid,model , type);
        Object list = redisTemplate.opsForValue().get(cacheKey);
        //缓存中没有数据，从数据库中查询
        if (list == null){
            QueryWrapper<Answer> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid",uid);
            queryWrapper.eq("type",type);
            queryWrapper.eq("model",model);
            queryWrapper.orderByDesc("aid"); //createtime也可以，但aid是主键，聚簇索引查询效率高
            List<Answer> dataList=answerService.list(queryWrapper);
            // 存储到缓存中
            redisTemplate.opsForValue().set(cacheKey,dataList,1, TimeUnit.DAYS);
            return ResponseEntity.success(dataList);
        }else {
            return ResponseEntity.success(list);
        }

    }

    /**
     * 获取 TongYi 绘图历史信息
     */
    @PostMapping("/getdrawlist")
    private ResponseEntity getDrawList(){
        Long uid =SecurityUtil.getCurrentUser().getUid();
        int type= AiTypeEnum.DRAW.getValue();
        int model = AiModelEnum.TONGYI.getValue();
        String cacheKey = AppVariable.getListCacheKey(uid,model , type);
        Object list = redisTemplate.opsForValue().get(cacheKey);
        if (list == null){
            QueryWrapper<Answer> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid",uid);
            queryWrapper.eq("type",AiTypeEnum.DRAW.getValue());
            queryWrapper.eq("model",AiModelEnum.TONGYI.getValue());
            queryWrapper.orderByDesc("aid"); //createtime也可以，但aid是主键，聚簇索引查询效率高
            List<Answer> dataList=answerService.list(queryWrapper);
            // 存储到缓存中
            redisTemplate.opsForValue().set(cacheKey,dataList,1, TimeUnit.DAYS);
            return ResponseEntity.success(dataList);
        }else {
            return ResponseEntity.success(list);
        }

    }
}
